﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
//"F:\Gitee\csharp-foundation\Bian\24 csharp 面向对象 析构\bin\Debug\netcoreapp3.1\24 csharp 面向对象 析构.exe"
namespace _24_csharp_面向对象_析构
{
    class Program
    {
        static void Main(string[] args)
        {
            CCC CC = new CCC();
            CC.a = new object();
            Person p = new Person();
            Console.WriteLine("end of main function");
            MyTest test = new MyTest();
            test = null;

            Console.WriteLine(GC.GetGeneration(CC));
            GC.Collect();
           GC.WaitForPendingFinalizers();
           // Console.ReadLine();
        }

        public class MyTest
        {
            //构造函数
            public MyTest()
            {
                System.Diagnostics.Debug.WriteLine("类开始实例化，构造函数被调用");
                Console.WriteLine("构造函数");
            }

            ~MyTest()
            {
                System.Diagnostics.Debug.WriteLine("程序退出，析构函数被调用");
                Console.WriteLine("析构函数");
            }
        }


        class Person
        {
            List<object> food;

            public Person()
            {
                food = new List<object>();
                food.Add("饼");
            }

            // 语法： 波浪号（~） 加上 类型名。
            // 析构函数：帮助回收废弃对象的内存
            // 定义被抛弃的对象如何降解（如何清内存）
            // 引用链 的断开，方便 GC 的回收 （GC ： garbage collection ，垃圾回收）
            // 一个人存在的价值是 ：被人需要 ，没被人需要 被 GC

            // 从语法基础约定就已经知道：
            // 1. 不能写访问修饰符，所以不能继承 ，不能 被重载（override）
            // 2. 因为类型的成员不能重名，所以只能有一个析构函数
            // 3. 无法调用析构函数。 它们是被自动调用的。
            // 4. 析构函数既没有修饰符，也没有参数。
            // 5. 不应使用空析构函数。 如果析构函数为空，只会导致不必要的性能损失。
            ~Person()
            {
                //clear 清洁，清除
                // 通过 list 的 清除 动作，断开 person 实例对list 内对象的引用，断开引用链
                // 树倒猢狲散
                food.Clear();
                System.Diagnostics.Debug.WriteLine("程序退出，析构函数被调用");
                Console.WriteLine("5555");
            }
        }

        // 析构的执行顺序
        class AAA
        {
            public object a;
            public AAA()
            {
                a = "";
            }
            ~AAA()
            {
                a = null;
                System.Diagnostics.Debug.WriteLine("AAA");
                Console.WriteLine("析构函数");
            }
        }

        class BBB : AAA
        {
            ~BBB()
            {
                System.Diagnostics.Debug.WriteLine("BBB");
                Console.WriteLine("析构函数");
            }
        }
        class CCC : BBB
        {
            ~CCC()
            {
                System.Diagnostics.Debug.WriteLine("CCC");
                Console.WriteLine("析构函数");
            }
        }

    }
}
